#pragma once;

#include "SceneNode.h"
#include "ModelSceneNode.h"

// Quickly Build Scene Graph containing a Bipedal Mecha using Parameters and
// exposed mothods to control the articulations on the Mecha's joints.
class BipedalMecha : public SceneNode
{

public:
	BipedalMecha();
	~BipedalMecha();

	///////////////////////////////////////////////////////////////////////////////
	// The methods that are used to apply Geometry to the mechas
	
	// Sets the Geometry that represents the pelvis.
	void SetPelvis(SceneNode* node);

	void SetLowerTorso(SceneNode* node);
	void SetTorso(SceneNode* node);
	void SetChest(SceneNode* node);

	void SetNeck(SceneNode* node);
	void SetHead(SceneNode* node);

	void SetLeftChest(SceneNode* node);
	void SetLeftShoulder(SceneNode* node);
	void SetLeftUpperArm(SceneNode* node);
	void SetLeftForearm(SceneNode* node);
	void SetLeftHand(SceneNode* node);
	void SetLeftFingers(SceneNode* node);

	void SetRightChest(SceneNode* node);
	void SetRightShoulder(SceneNode* node);
	void SetRightUpperArm(SceneNode* node);
	void SetRightForearm(SceneNode* node);
	void SetRightHand(SceneNode* node);
	void SetRightFingers(SceneNode* node);

	void SetLeftPelvis(SceneNode* node);
	void SetLeftThigh(SceneNode* node);
	void SetLeftShin(SceneNode* node);
	void SetLeftFoot(SceneNode* node);
	void SetLeftToe(SceneNode* node);

	void SetRightPelvis(SceneNode* node);
	void SetRightThigh(SceneNode* node);
	void SetRightShin(SceneNode* node);
	void SetRightFoot(SceneNode* node);
	void SetRightToe(SceneNode* node);

	///////////////////////////////////////////////////////////////////////////////
	// The methods that exposes the parametes to control the dimensions of each 
	// limb.

	// Sets basic parameters to create a basic skeleton of a mecha.
	void SetBasicMechaDimensions(
		float NeckHeight, float HeadHeight,
		float LowerTorsoLength, float TorsoLength, float ChestHeight, 
		float ChestWidth,
		float ShoulderWidth, float UpperArmLength, float ForearmLength, float HandLength, float FingersLength,
		float PelvisWidth, float ThighLength, float ShinLength, float FootHeight, float FootLength, float ToeLength,
		bool CreateWithBoxGeometry,

		ID3D11Device *d3dDevice,
		
		ShapeLibrary* ShapeLibrary,
		int TextureID,
		int ShaderID,
		ModelLibrary* ModelLibrary);

	void SetPelvisSize(float x, float y, float z);
	void SetLowerTorsoSize(float x, float y, float z);
	void SetTorsoSize(float x, float y, float z);
	void SetChestSize(float x, float y, float z);
	void SetNeckSize(float x, float y, float z);
	void SetHeadSize(float x, float y, float z);

	void SetLeftChestSize(float x, float y, float z);
	void SetLeftShoulderSize(float x, float y, float z);
	void SetLeftUpperArmSize(float x, float y, float z);
	void SetLeftForearmSize(float x, float y, float z);
	void SetLeftHandSize(float x, float y, float z);
	void SetLeftFingersSize(float x, float y, float z);

	void SetRightChestSize(float x, float y, float z);
	void SetRightShoulderSize(float x, float y, float z);
	void SetRightUpperArmSize(float x, float y, float z);
	void SetRightForearmSize(float x, float y, float z);
	void SetRightHandSize(float x, float y, float z);
	void SetRightFingersSize(float x, float y, float z);

	void SetLeftPelvisSize(float x, float y, float z);
	void SetLeftThighSize(float x, float y, float z);
	void SetLeftShinSize(float x, float y, float z);
	void SetLeftFootSize(float x, float y, float z);
	void SetLeftToesSize(float x, float y, float z);

	void SetRightPelvisSize(float x, float y, float z);
	void SetRightThighSize(float x, float y, float z);
	void SetRightShinSize(float x, float y, float z);
	void SetRightFootSize(float x, float y, float z);
	void SetRightToesSize(float x, float y, float z);

	///////////////////////////////////////////////////////////////////////////////
	// The methods that exposes the parameters to control the Joints of the 
	// mecha

	// The Center of mass
	void SetRelativeCOM(float x, float y, float z);

	// The Pelvis, Torso, Chest
	void RotateLowerTorso(float x, float y, float z);
	void RotateTorso(float x, float y, float z);
	void RotateChest(float x, float y, float z);

	// The neck and Head
	void RotateNeck(float x, float y, float z);
	void RotateHead(float x, float y, float z);

	// The Legs:
	void RotateLeftPelvisY(float y);
	void RotateLeftHip(float x, float y, float z);
	void RotateLeftKnee(float x);
	void RotateLeftAnkle(float x, float z);
	void RotateLeftToe(float x);

	void RotateRightPelvisY(float y);
	void RotateRightHip(float x, float y, float z);
	void RotateRightKnee(float x);
	void RotateRightAnkle(float x, float z);
	void RotateRightToe(float x);

	// The Arms:
	void RotateLeftChestY(float y);
	void RotateLeftShoulder(float x, float y, float z);
	void RotateLeftElbow(float x, float y);
	void RotateLeftWrist(float x, float z);
	void RotateLeftFingers(float x);

	void RotateRightChestY(float y);
	void RotateRightShoulder(float x, float y, float z);
	void RotateRightElbow(float x, float y);
	void RotateRightWrist(float x, float z);
	void RotateRightFingers(float x);


private:
	// Initializes the scene graph that is used to represent the Bipedal mecha.
	void InitializeBipedalSceneGraph();

	///////////////////////////////////////////////////////////////////////////////
	// The joints of the mecha
	
	// Represents the transformation from the Mecha's position in the world to it's 
	// pelvis.
	SceneNode* centerOfMass;

	SceneNode* jointLowerTorso;
	SceneNode* jointTorso;
	SceneNode* jointChest;

	SceneNode* jointNeck;
	SceneNode* jointHead;

	SceneNode* jointLeftChest;
	SceneNode* jointLeftShoulder;
	SceneNode* jointLeftUpperArm;
	SceneNode* jointLeftElbow;
	SceneNode* jointLeftWrist;
	SceneNode* jointLeftFingers;

	SceneNode* jointRightChest;
	SceneNode* jointRightShoulder;
	SceneNode* jointRightUpperArm;
	SceneNode* jointRightElbow;
	SceneNode* jointRightWrist;
	SceneNode* jointRightFingers;

	SceneNode* jointLeftPelvis;
	SceneNode* jointLeftHip;
	SceneNode* jointLeftKnee;
	SceneNode* jointLeftAnkle;
	SceneNode* jointLeftToes;

	SceneNode* jointRightPelvis;
	SceneNode* jointRightHip;
	SceneNode* jointRightKnee;
	SceneNode* jointRightAnkle;
	SceneNode* jointRightToes;

	///////////////////////////////////////////////////////////////////////////////
	// The Geometry of the Mecha

	SceneNode* pelvis;
	SceneNode* lowerTorso;
	SceneNode* torso;
	SceneNode* chest;

	SceneNode* neck;

	SceneNode* head;
	
	SceneNode* leftChest;
	SceneNode* leftShoulder;
	SceneNode* leftUpperArm;
	SceneNode* leftForearm;
	SceneNode* leftHand;
	SceneNode* leftFingers;

	SceneNode* rightChest;
	SceneNode* rightShoulder;
	SceneNode* rightUpperArm;
	SceneNode* rightForearm;
	SceneNode* rightHand;
	SceneNode* rightFingers;

	SceneNode* leftPelvis;
	SceneNode* leftThigh;
	SceneNode* leftShin;
	SceneNode* leftFoot;
	SceneNode* leftToes;

	SceneNode* rightPelvis;
	SceneNode* rightThigh;
	SceneNode* rightShin;
	SceneNode* rightFoot;
	SceneNode* rightToes;

	


	ModelSceneNode* CreateSimpleBox(
		float left, 
		float top, 
		float right, 
		float bot,
		float front, 
		float back,

		ID3D11Device *d3dDevice,

		ShapeLibrary* ShapeLibrary,
		int TextureID,
		int ShaderID,
		ModelLibrary* ModelLibrary);



};